﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using VsxFactory.Modeling.VisualStudio;
using VsxFactory.Modeling.Strategies;

namespace VsxFactory.Modeling.StrategyManager.Strategies
{
    /// <summary>
    /// Provider d'extender pour les modéles
    /// </summary>
    [GuidAttribute(DependencyFileStrategyModelExtenderProvider.Guid)]
    class DependencyFileStrategyModelExtenderProvider : StrategyExtenderProvider 
    {
        private DependentFileStrategyProvider strategyProvider;

        public const string Guid = "5B424DFD-E540-4AE5-B9D7-7B7A8AB4FEB4";
        private string[] knownExtensions = { ".tt", ".cs", ".vb", ".aspx", ".ashx", ".csproj", ".vbproj", ".asmx", ".svc", ".config", ".dll", ".resx", ".exe", ".snk" };
        private IEnumerable<Lazy<Modeling.Strategies.IGenerationStrategy, Modeling.Strategies.IStrategyMetadata>> strategies;

        public DependencyFileStrategyModelExtenderProvider(DependentFileStrategyProvider strategyProvider) : base(strategyProvider.ServiceProvider)
        {
            System.Diagnostics.Contracts.Contract.Requires(strategyProvider != null);

            this.strategyProvider = strategyProvider;
            this.strategies = strategyProvider.Strategies;
        }

        public override string Name
        {
            get { return "DependencyFileStrategyModelExtender"; }
        }

        /// <summary>
        /// Vérifie que le document est un modéle
        /// </summary>
        /// <param name="fullPath">Chemin du fichier à tester</param>
        /// <returns></returns>
        protected override bool CanExtendFile(string fullPath)
        {
            System.Diagnostics.Contracts.Contract.Requires(fullPath != null);

            string ext = Path.GetExtension(fullPath);
            bool flag = !knownExtensions.Contains(ext); // Prefiltre sur les extensions courantes qui ne peuvent pas être des modéles
            if (flag)
            {
                if (ext.Equals(".edmx", StringComparison.InvariantCultureIgnoreCase))
                    return true;

                try
                {
                    // Test si c'est un modéle
                    IStrategyManager sm = ServiceProvider.GetService(typeof(SStrategyManager)) as IStrategyManager;
                    var n = sm.SolutionExplorer.CurrentSolution.FindByPath<IVsProjectFileItem>(fullPath);
                    if (n != null)
                    {
                        // Optimisation. Si le 1er fichier liée est un .diagram
                        if ( n.AllElements.FirstOrDefault(c => Path.GetExtension(c.Name).Equals(".diagram", StringComparison.InvariantCultureIgnoreCase)) != null)
                            return true;
                        var docdata = ((HierarchyNode)n.ExternalObject).GetDocData(System.Guid.Empty);
                        flag = docdata is Microsoft.VisualStudio.Modeling.Shell.ModelingDocData;
                    }
                }
                catch { }
            }
            return flag;
        }

        protected override IStrategyExtender CreateExtender(IVsProjectFileItem node)
        {
            System.Diagnostics.Contracts.Contract.Requires(node != null);

            var e = new DependencyFileStrategyModelExtender(ServiceProvider, node, strategies);
            return e;
        }
    }
}
